package com.dragon.graduation.projectApplication.controller;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dragon.config.exception.exception.GlobalException;
import com.dragon.field.FieldUtil;
import com.dragon.graduation.project.entity.ProjectEntity;
import com.dragon.graduation.project.service.ProjectService;
import com.dragon.graduation.projectApplication.controller.bo.ProjectTeacherBO;
import com.dragon.graduation.projectApplication.controller.dto.ApplicationAuditDTO;
import com.dragon.graduation.projectApplication.controller.dto.ProjectApplicationAddDTO;
import com.dragon.graduation.projectApplication.controller.dto.ProjectApplicationSearchDTO;
import com.dragon.graduation.projectApplication.controller.dto.ProjectApplicationUpdateDTO;
import com.dragon.graduation.projectApplication.controller.vo.ProjectApplicationVO;
import com.dragon.graduation.projectApplication.entity.ProjectApplicationEntity;
import com.dragon.graduation.projectApplication.service.ProjectApplicationService;
import com.dragon.graduation.projectProgress.service.ProjectProgressService;
import com.dragon.graduation.projectTeacher.service.ProjectTeacherService;
import com.dragon.graduation.student.entity.StudentEntity;
import com.dragon.graduation.student.service.StudentService;
import com.dragon.graduation.user.controller.vo.UserVO;
import com.dragon.jwt.JwtUtil;
import com.dragon.results.page.ResultPage;
import com.dragon.results.result.HttpResult;
import com.dragon.results.util.response.SortVO;
import com.dragon.util.MyPage;
import com.dragon.util.WrapperUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 选题申请表 前端控制器
 * </p>
 *
 * @author dragon
 * @since 2025-02-28 21:20:09
 */
@RestController
@RequestMapping("/projectApplication")
@RequiredArgsConstructor
@Api(tags = "选题申请表 相关接口")
public class ProjectApplicationController {

    private final ProjectApplicationService projectApplicationService;
    private final ProjectService projectService;
    private final ProjectTeacherService projectTeacherService;
    private final StudentService studentService;
    private final ProjectProgressService projectProgressService;


    @PostMapping("add")
    @ApiOperation("1]选题申请表添加")
    @ApiOperationSupport(order = 1)
    public HttpResult<String> add(@RequestBody ProjectApplicationAddDTO addDTO) {
        ProjectApplicationEntity entity = ProjectApplicationAddDTO.to(addDTO, ProjectApplicationEntity.class);
        projectApplicationService.save(entity);
        return HttpResult.ok("添加成功");
    }

    @PostMapping("update")
    @ApiOperation("2]选题申请表修改")
    @ApiOperationSupport(order = 2)
    public HttpResult<String> update(@RequestBody ProjectApplicationUpdateDTO updateDTO) {
        ProjectApplicationEntity entity = projectApplicationService.getById(updateDTO.getId());
        Assert.isFalse(ObjectUtils.isEmpty(entity), () -> new GlobalException("要修改的数据不存在"));
        entity = ProjectApplicationUpdateDTO.to(updateDTO, ProjectApplicationEntity.class);
        projectApplicationService.updateById(entity);
        return HttpResult.ok("修改成功");
    }

    @PostMapping("search")
    @ApiOperation("3]选题申请表分页查询")
    @ApiOperationSupport(order = 3)
    public HttpResult<ResultPage<List<ProjectApplicationVO>>> search(@RequestBody ProjectApplicationSearchDTO searchDTO) {

        if (StringUtils.isNotBlank(searchDTO.getProjectName())) {
            List<ProjectEntity> projectEntities = projectService.lambdaQuery().like(ProjectEntity::getTitle, searchDTO.getProjectName()).list();
            List<Integer> collected = projectEntities.stream().map(ProjectEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collected)) {
                return HttpResult.okForData(new ResultPage<>());
            }
            searchDTO.setProjectId(collected);
        }

        QueryWrapper<ProjectApplicationEntity> queryWrapper = WrapperUtil.constructWrapper(searchDTO, ProjectApplicationEntity.class);

        UserVO userVO = JwtUtil.parseToken(JwtUtil.getTokenFromRequest(), UserVO.class);
        if (userVO.getRole() != 1) {
            if (userVO.getRole() == 2) {
                //学生角色
                queryWrapper.eq(FieldUtil.getFieldName(ProjectApplicationEntity::getStudentId, true), userVO.getRoleId());

            } else {
                //老师角色
                List<ProjectEntity> projectEntities = projectService.lambdaQuery().eq(ProjectEntity::getTeacherId, userVO.getRoleId()).list();
                List<Integer> projectIdList = projectEntities.stream().map(ProjectEntity::getId).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(projectIdList)) {
                    return HttpResult.okForData(new ResultPage<>());
                } else {
                    queryWrapper.in(FieldUtil.getFieldName(ProjectApplicationEntity::getProjectId, true), projectIdList);
                }
            }
        }
        SortVO sortVO = new SortVO();
        sortVO.setOrderBy(FieldUtil.getFieldName(ProjectApplicationEntity::getUpdateTime, true));
        sortVO.setOrderDesc(1);
        Page<ProjectApplicationEntity> entityPage = MyPage.setPageSort(ProjectApplicationEntity.class, searchDTO.getPage(), sortVO);
        Page<ProjectApplicationEntity> page = projectApplicationService.page(entityPage, queryWrapper);
        ResultPage<List<ProjectApplicationVO>> resultPage = MyPage.copyPage(page, ProjectApplicationVO.class);
        //获取教师 获取题目id，根据题目id查找教师
        List<ProjectApplicationVO> records = resultPage.getRecords();
        List<Integer> projectIdList = records.stream().map(ProjectApplicationVO::getProjectId).collect(Collectors.toList());

        Map<Integer, ProjectTeacherBO> teacherBOMap = new HashMap<>();
        Map<Integer, ProjectEntity> projectEntityMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(projectIdList)) {
            List<ProjectTeacherBO> teacherList = projectTeacherService.getByProjectIds(projectIdList);
            teacherBOMap = teacherList.stream().collect(Collectors.toMap(ProjectTeacherBO::getProjectId, t -> t));
            List<ProjectEntity> projectEntityList = projectService.listByIds(projectIdList);
            projectEntityMap = projectEntityList.stream().collect(Collectors.toMap(ProjectEntity::getId, t -> t));
        }

        //获取学生
        List<Integer> studentIdList = records.stream().map(ProjectApplicationVO::getStudentId).collect(Collectors.toList());
        Map<Integer, StudentEntity> studentEntityMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(studentIdList)) {
            List<StudentEntity> studentEntityList = studentService.listByIds(studentIdList);
            studentEntityMap = studentEntityList.stream().collect(Collectors.toMap(StudentEntity::getId, t -> t));
        }

        for (ProjectApplicationVO record : records) {
            if (ObjectUtils.isNotEmpty(teacherBOMap.get(record.getProjectId()))) {
                record.setTeacherName(teacherBOMap.get(record.getProjectId()).getTeacherName());
            }
            if (ObjectUtils.isNotEmpty(projectEntityMap.get(record.getProjectId()))) {
                record.setProjectName(projectEntityMap.get(record.getProjectId()).getTitle());
            }
            if (ObjectUtils.isNotEmpty(studentEntityMap.get(record.getStudentId()))) {
                record.setStudentName(studentEntityMap.get(record.getStudentId()).getStudentName());
            }
        }

        return HttpResult.okForData(resultPage);
    }

    @PostMapping("delete")
    @ApiOperation("4]选题申请表删除")
    @ApiOperationSupport(order = 4)
    public HttpResult<String> delete(@RequestBody List<Integer> idList) {
        projectApplicationService.removeByIds(idList);
        return HttpResult.ok("删除成功");
    }

    @GetMapping("apply")
    @ApiOperation("5]申请题目")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParam(name = "projectId", value = "题目id", required = true, dataType = "Integer", paramType = "query")
    public HttpResult<String> apply(Integer projectId) {
        UserVO userVO = JwtUtil.parseToken(JwtUtil.getTokenFromRequest(), UserVO.class);
        ProjectApplicationEntity entity = projectApplicationService.getByProjectIdAndStudentId(projectId, userVO.getRoleId());
        Assert.isFalse(ObjectUtils.isNotEmpty(entity), () -> new GlobalException("您已申请过该题目，不可重复申请"));
        Long counted = projectApplicationService.lambdaQuery().eq(ProjectApplicationEntity::getStudentId, userVO.getRoleId()).in(ProjectApplicationEntity::getStatus, 0, 1).count();
        Assert.isFalse(counted > 0, () -> new GlobalException("您已申请过题目，不可再次申请!"));
        ProjectApplicationEntity build = ProjectApplicationEntity.builder()
                .projectId(projectId)
                .studentId(userVO.getRoleId())
                .applyTime(LocalDateTime.now())
                .status(0)
                .build();
        projectApplicationService.save(build);
        //记录
        projectProgressService.record(userVO.getRoleId(),projectId,1,0);
        return HttpResult.ok("申请成功");
    }

    @PostMapping("audit")
    @ApiOperation("6]审核申请")
    @ApiOperationSupport(order = 6)
    public HttpResult<String> audit(@RequestBody ApplicationAuditDTO auditDTO) {
        ProjectApplicationEntity entity = projectApplicationService.getById(auditDTO.getId());
        Assert.isFalse(ObjectUtils.isEmpty(entity), () -> new GlobalException("要审核的数据不存在"));
        Assert.isFalse(entity.getStatus() != 0, () -> new GlobalException("该申请已审核;不可重复审核"));
        entity.setStatus(auditDTO.getStatus());
        entity.setReviewComment(auditDTO.getReviewComment());
        UserVO userVO = JwtUtil.parseToken(JwtUtil.getTokenFromRequest(), UserVO.class);
        entity.setReviewerId(userVO.getId());
        entity.setReviewName(userVO.getRealName());
        entity.setReviewTime(LocalDateTime.now());
        projectApplicationService.updateById(entity);
        //审核通过
        if (auditDTO.getStatus() == 1) {
            //更新题目表
            ProjectEntity projectEntity = projectService.getById(entity.getProjectId());
            projectEntity.setCurrentSelected(projectEntity.getCurrentSelected() + 1);
            projectService.updateById(projectEntity);
            projectProgressService.record(entity.getStudentId(),entity.getProjectId(),1,1);
        }else {
            projectProgressService.record(entity.getStudentId(),entity.getProjectId(),1,2);
        }
        return HttpResult.ok("操作成功");
    }
}
